from . import schema
from typing import List
from fastapi import APIRouter, Depends, Security, Request
from fastapi.responses import RedirectResponse
from fastapi.security import OAuth2PasswordRequestForm
from package.connector.sql_db import db
from package.fastapi import permission
from .view import ApikeyView, OIDCView, AuthView


router_auth = APIRouter(prefix='/auth', tags=['Auth'])
router_meta = {'module': 'System', 'sub_module': 'Auth'}

router_apikey = APIRouter(prefix='/apikey', tags=['ApiKey'])
apikey_meta = {'module': 'System', 'sub_module': 'ApiKey'}

router_oidc = APIRouter(prefix='/oidc', tags=['OIDC'])
oidc_meta = {'module': 'System', 'sub_module': 'OIDC'}


@router_auth.post('/token', openapi_extra=router_meta, name='auth_token_form', summary='Token获取-Form')
@AuthView.auth_safe
def token_form(form: OAuth2PasswordRequestForm = Depends(),
               session=Depends(db.get_session),
               request: Request = None):
    username = form.username
    password = form.password
    return AuthView.post_token(session, name=username, password=password, request=request)


@router_auth.post('/login', openapi_extra=router_meta, name='auth_token_login', summary='Token获取')
@AuthView.auth_safe
def token_body(body: schema.Login,
               request: Request = None,
               session=Depends(db.get_session)):
    return AuthView.post_token(session, name=body.name, password=body.password, request=request)


# ------------------------------------------apikey----------------------------------------------------------------
@router_apikey.get('/', response_model=List[schema.ApiKeyOut], openapi_extra=router_meta, name='apikey_get',
                   summary='apikey获取')
def apikey_get(session=Depends(db.get_session),
               user=Security(permission.security, scopes=['apikey:read'])):
    return ApikeyView.get_items(session).all()


@router_apikey.post('/', response_model=schema.ApiKeyOut, openapi_extra=router_meta, name='apikey_post',
                    summary='apikey添加')
def apikey_post(body: schema.ApiKeyIn,
                session=Depends(db.get_session),
                user=Security(permission.security, scopes=['apikey:write'])):
    return ApikeyView.create_apikey(session, body.dict())


@router_apikey.patch('/{id}', response_model=schema.ApiKeyOut, openapi_extra=router_meta, name='apikey_patch',
                     summary='apikey修改')
def apikey_post(id: str,
                body: schema.ApiKeyEdit,
                session=Depends(db.get_session),
                user=Security(permission.security, scopes=['apikey:write'])):
    return ApikeyView.update_apikey(session, body.dict(exclude_unset=True), id)


@router_apikey.delete('/', openapi_extra=router_meta, name='apikey_delete', summary='apikey添加')
def apikey_delete(body: schema.BatchId,
                  session=Depends(db.get_session),
                  user=Security(permission.security, scopes=['apikey:write'])):
    return ApikeyView.delete_apikey(session, body.ids)


# ------------------------------------------oidc----------------------------------------------------------------
@router_oidc.get('/', response_model=schema.PageOidc, openapi_extra=router_meta, name='oidc_get',
                 summary='oidc获取')
def oidc_get(q: str = None,
             page: int = 1,
             page_size: int = 10,
             order_by: str = 'created_at desc',
             session=Depends(db.get_session)):
    return OIDCView.get_page_items(session, q=q, page=page, page_size=page_size, order_by=order_by)


@router_oidc.post('/', response_model=schema.OidcOut, openapi_extra=router_meta, name='oidc_post',
                  summary='oidc添加')
def oidc_post(body: schema.OidcIn,
              session=Depends(db.get_session),
              user=Security(permission.security, scopes=['oidc:write'])):
    return OIDCView.create_item(session, body.dict())


@router_oidc.patch('/{id}', response_model=schema.OidcOut, openapi_extra=router_meta, name='oidc_patch',
                   summary='oidc修改')
def oidc_post(id: str,
              body: schema.OidcEdit,
              session=Depends(db.get_session),
              user=Security(permission.security, scopes=['oidc:write'])):
    return OIDCView.update_item(session, filter_=[OIDCView.id == id], update=body.dict(exclude_unset=True))


@router_oidc.delete('/', openapi_extra=router_meta, name='oidc_delete', summary='oidc删除')
def oidc_delete(body: schema.BatchId,
                session=Depends(db.get_session),
                user=Security(permission.security, scopes=['oidc:write'])):
    return OIDCView.delete_items(session, filter_=[OIDCView.id.in_(body.ids)])


@router_oidc.get('/auth/sign', openapi_extra=router_meta, name='oidc_sign', summary='OIDC登陆')
def oidc_sign(state: str = '',
              session=Depends(db.get_session)):
    return RedirectResponse(OIDCView.oidc_sign(session, state))


@router_oidc.get('/auth/callback', openapi_extra=router_meta, name='oidc_callback', summary='OIDC回调接口')
def oidc_callback(code: str = '',
                  state: str = '',
                  session=Depends(db.get_session),
                  request: Request = None):
    return OIDCView.oidc_callback(session, code, state, request=request)
